累積和
数列の連続部分列の総和を取りたい素朴に取ると部分列の長さのオーダー事前に先頭からの話を取っておくことでO(1)で求められる準備にO(N)かかるN回くらい繰り返す時に使うと得
def solve(N, XS):
accum = list(accumulate(XS)) + [0]
def sub(L, R):
if L == R:
return 0
ret = INF
for x in range(L, R):
v = sub(L, x) + sub(x + 1, R)
if v < ret:
ret = v
return ret + accum[R] - accum[L - 1]
return sub(0, N - 1)
cdef long long[400 * 400] table
cdef long long[410] accum
cdef sub(long L, long R):
cdef long long ret
if L == R:
return 0
ret = table[L * 400 + R]
if ret != 0:
return ret
ret = INF
for x in range(L, R):
v = sub(L, x) + sub(x + 1, R)
if v < ret:
ret = v
ret += accum[R + 1] - accum[L]
table[L * 400 + R] = ret
return ret
cdef solve(N, XS):
cdef long i
cdef long long v
v = 0
accum[0] = 0
for i in range(N):
v += XS[i]
accum[i + 1] = v
return sub(0, N - 1)